package com.github.baichuan.iot.gateway.context;

import lombok.NonNull;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.Consumer;

/**
 * 设备上下文信息缓存
 */
public abstract class DeviceContextCache {
    protected DeviceContextSupplier contextSupplier;

    private ThreadPoolTaskExecutor taskExecutor;

    /**
     * 设备上线事件监听器
     */
    private List<Consumer<DeviceContext>> onlineListens = new CopyOnWriteArrayList<>();

    /**
     * 设备离线事件监听器
     */
    private List<Consumer<DeviceContext>> offlineListens = new CopyOnWriteArrayList<>();

    public DeviceContextCache(@NonNull DeviceContextSupplier contextSupplier, @NonNull ThreadPoolTaskExecutor taskExecutor){
        this.contextSupplier = contextSupplier;
        this.taskExecutor = taskExecutor;
    }

    public abstract DeviceContext get(String device);

    public abstract boolean contains(String device);

    /**
     * 将设备从网关踢出，并断开与设备的网络联接
     */
    public abstract void evict(String device);

    /**
     * 刷新缓存信息
     */
    public abstract void refresh(String tbox);

    /**
     * 添加上线事件监听器
     */
    public void addOnlineListen(@NonNull Consumer<DeviceContext> listen){
        this.onlineListens.add(listen);
    }

    /**
     * 添加离线事件监听器
     */
    public void addOfflineListen(@NonNull Consumer<DeviceContext> listen){
        this.offlineListens.add(listen);
    }

    /**
     * 发布上线事件
     * @param context
     */
    public void online(DeviceContext context){
        this.onlineListens.stream().forEach(listen -> {
            taskExecutor.execute(() -> listen.accept(context));
        });
    }

    /**
     * 发布离线事件
     * @param context
     */
    public void offline(DeviceContext context){
        this.offlineListens.stream().forEach(listen -> {
            taskExecutor.execute(() -> listen.accept(context));
        });
    }
}
